#-------------------------------------------------------------------------------
# Copyright (c) 2012 Huseyin BIYIK.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0
# which accompanies this distribution, and is available at
# http://www.gnu.org/licenses/gpl.html
# 
# Contributors:
#     Huseyin BIYIK - initial API and implementation
#-------------------------------------------------------------------------------
import pyaudio, audioop, Queue, threading
from defs import *

debug = 0

class audio_interface(threading.Thread):
	def __init__(self):
		threading.Thread.__init__(self)
		self.isclosing = False
		self.is_active = False
		self.chunk = 10
		self.p = pyaudio.PyAudio()
		self.codec = "ulaw"
		self.q_mic = Queue.Queue(maxsize=10)
		self.q_spk = Queue.Queue(maxsize=10)
		self.start()

	def close(self):
		self.deactivate()
		self.isclosing = True
		threading.Thread.join(self)
		return True

	def activate(self):
		try:
			print "1"
			self.stream = self.p.open(format=pyaudio.paInt16, channels=1, rate=8000, input=True, output=True, frames_per_buffer=1024)
			print "2"
			self.is_active = True
		except IOError, e:
			logger.error("Audio interface cant start streaming: %s", e)

	def deactivate(self):
		if self.is_active:
			self.is_active = False
			self.stream.close()

	def put(self, packet):
		return self.q_spk.put(packet)
	
	def get(self):
		try:
			packet = self.q_mic.get(True, 1)
		except Queue.Empty:
			packet = ''
		return packet

	def run(self):
		while True:
			if self.isclosing:
				break
			if self.is_active:
				try:
					avail = self.stream.get_read_available()
					if avail > 0:
						print avail
					mic = self.stream.read(avail)
				except IOError, e:
					logger.error("Cant read from mic: %s", e)
					pass
				if mic:
					payload = audioop.lin2ulaw(mic, 2)
					self.q_mic.put(payload)
				##todo: consider compression, jitter and codecs
				if self.q_spk.qsize() > 0:
					packet = self.q_spk.get(True, 1)
					linear = None
					try:
						linear = audioop.ulaw2lin(packet, 2)
					except audioop.error:
						pass
					if linear:
						logger.debug("%d byte audio has been played", len(linear))
						self.stream.write(linear)
